5. Adding functionality with interceptors
5.1 How interceptors are called

- Interceptors는 action 과 result의 실행 전, 후에 특정한 작업을 처리할 수 있다.
- Interceptors는 action 실행후에는 실행전에 수행된 순서의 역으로 수행된다.
- interceptors의 그룹을 stack으로 지정하여 사용 할 수 있다
5.2 Using the prepackaged interceptors
- 교재 page 115~116 참고. 설명이 쭈~욱 나와있습니다.
5.2.1 Utility interceptors
Timing your actions
public String intercept(ActionInvocation invocation) throws Exception {
long startTime = System.currentTimeMillis();
String result = invocation.invoke();
long executionTime = System.currentTimeMillis() - startTime;
... log the time ...
}
The AroundInterceptor
- before() 와 after()가 정의되어 있음, 많은 interceptor들의 base class 역할을 함
public abstrac class AroundInterceptor implements Interceptor {
public String intercept(ActionInvocation invocation) throws Exception {
before(invocation);
result = invocation.invoke();
after(ivocation, result);
return result;
}
protected abstract void after(ActionInvocation dispatcher, String result) throws Exception;
protected abstract void before(ActionInvocation invocation) throws Exception;
}
Logging action executions
protected void after(ActionInvocation invocation, String result) throws Exception {
logMessage(invocation, FINISH_MESSAGE);
}
protected void before(ActionInvocation invocation) throws Exception {
logMessage(invocation, START_MESSAGE);
}
5.2.2 Setting parameters
setting properties from the request parameters
<ww:textfield label="Foo" name="foo"/>
- ParametersInterceptor sets the properties of the action from the request parameters.
if (parameters != null) {
final OgnlValueStack stack =
ActionContext.getContext().getValueStack();
for (Iterator iterator = parameters.entrySet().iterator();
iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
stack.setValue(entry.getKey().toString(), entry.getValue());
}
}
- request parameters의 key와 value들을 꺼내어 OgnlValueStack에 넣음
- OGNL(Object Graph Navigation Language)
- action의 setFoo() 설정
- ParametersInterceptor를 사용, default-webwork.xml에 params로 설정되어 있음
Setting properties from the configuration
- xwork.xml 파일에 설정. 항상 일정한 값을 갖는다.
- StaticParametersInterceptor를 사용, default-webwork.xml에 static-params로 설정되어 있음
<action name="exampleAction" class="example.ExampleAction">
<param name="firstName">John</param>
<param name="lastName">Doe</param>
</action>
Setting properties on your action from a chained action
- ChainingInterceptor를 사용
- action chain을 구현할때 사용한다. 이전에 수행된 액션의 속성들을 현재 액션에서도 사용할 수 있게 해준다
- 7장 "Using results"에서 소개함
Getting at the HTTP-specific objects when you need them
- ServletConfigInterceptor를 사용하여 Action에서 HttpServletRequest나 HttpServletResponse에 대해 접근할 수 있도록 해준다
Handling file uploads
- FileUploadInterceptor를 사용하여 파일업로드를 처리한다
5.2.3 Defining workflow
Using the default workflow
- DefaultWorkflowInterceptor : validation을 수행하고, 에러 발생시 error result를 반환한다.
Preparing your actions
- PrepareInterceptor사용. com.opensymphony.xwork.Preparable interface를 구현한 Action일 경우 prepare 메소드를 실행한다
Making your actions ModelDriven
- ModelDrivenInterceptor사용. action이 ModelDriven을 implement하고 있다면 getModel()을 호출해 준다. 4.6 참조.
Preventing duplicate form posting using form tokens
- TokenInterceptor/TokenSessionInterceptor 사용,
- 똑같은 submission이 두 번 오면, 두번째 온다는 것을 detect해서 에러를 내든지 첫번째 submission의 결과를 다시 보여주든지 하게 할 수 있다.
- 15.6장 참조.
Excuting long-running actions without making the user wait
- ExecuteandWaitInterceptor : action 수행하는 동안 백그라운드로 처리하고, action 수행 끝나면 그 결과를 보낸다. 15.7 참조.
5.3 Using prepackaged interceptor stacks
- interceptor stack : interceptor들의 묶음
- 보통 interceptor 단독으로 사용되지는 않고 stack으로 묶어 특정 순서로 사용할 수 있다.
- webwork-default.xml에 기본적으로 정의되어 있다.
- page 126~127 참고
5.4 Building your own interceptors
- 개발자가 인터셉터를 생성하여 action실행시에 적용할 수 있다.
5.4.2 Looking at an example custom interceptor
- AuthenticationInterceptor: checks the user logon
public class AuthenticationInterceptor implements Interceptor {
public static final String USER = "user";
public void destroy() {
}
public void init() {
}
public String intercept (ActionInvocation actionInvocation) throws Exception {
Map session = actionInvocation.getInvocationContext().getSession();
User user = (User) session.get(USER);
if (user == null) {
return Action.LOGIN;
} else {
Action action = actionInvocation.getAction();
if (action instanceof UserAware) {
((UserAware)action).setUser(user);
}
return actionInvocation.invoke(); //action 수행
}
}
}
<global-results>
<result name="login" type="redirect">/login!default.action</result>
<result name="invalid.token">/invalidToken.jsp</result>
</global-results>
public class Login extends ActionSupport implements SessionAware, UserDAOAware {
Map session;
User user;
private UserDAO userDAO;
public void setSession(Map session) {
this.session = session;
}
public String execute() throws Exception {
user = userDAO.findByCredentials(user.getUsername(), user.getPassword());
if (user == null) {
return INPUT;
} else {
session.put(AuthenticationInterceptor.USER, user);
return SUCCESS;
}
}
public String doDefault() throws Exception() {
return INPUT;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void setUserDAO(UserDAO dao) {
this.userDAO = dao;
}
}
- 사용자 정의 interceptor 적용 순서
- interceptor 작성
- xwork.xml에 interceptor 선언
- 해당 interceptor를 적용하고자 하는 action의 선언부분에 interceptor-ref 설정
5.5 Interceptors vs. servlet filters
문서에 대하여